home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v7n16.arc / SFIND.C < prev    next >
C/C++ Source or Header  |  1988-09-13  |  6KB  |  177 lines

  1. /* sfind.c
  2.     Searches all Microsoft Word .DOC files in the default directory
  3.         for a string.
  4.     To compile MSC 4.0/5.0 and QuickC 1.0:  cl sfind.c
  5.  */
  6.     
  7. #include <stdio.h>
  8. #include <dos.h>
  9. #include <string.h>
  10.  
  11. #define DYEAR(x) (x>>9)+80     /* These macros breakdown the calendar and */
  12. #define DMON(x)  x>>5 & 0x000f /* time info to individual bytes */
  13. #define DDAY(x) x & 0x001f
  14. #define DHOUR(x) x>>11
  15. #define DMIN(x) x>>5 & 0x003f
  16. #define DSEC(x) x<<1 & 0x003f
  17.  
  18. #define BUFSIZE 30000             /* Program can hold a max of 30k bytes */
  19. #define MAXFILES 500
  20. #define WORD_HEADER_SIZE 128      /* size of Word's header in .DOC file */
  21.  
  22. struct fdir
  23.     unsigned char fname[13];      /* string containing the filename */ 
  24.     unsigned char attrib;         /* file attribute */
  25.     int fhour;                    /* time */
  26.     int fmin;
  27.     int fsec;  
  28.     int fday;                     /* date */
  29.     int fmon;
  30.     int fyear;                        
  31.     long fsize;                   /* size of file */ 
  32. } fdata[MAXFILES];                /* program can read up to MAXFILES files */
  33.  
  34. struct find_t ff_area;            /* defined in dos.h */
  35.  
  36. char *scompare(FILE *,char *,const char *,int);
  37.  
  38. main(int argc,char *argv[])
  39. {
  40.     int numfound=0;
  41.     const char *string;         /* pointer to text to find */
  42.  
  43.     if(argc<2)
  44.     {
  45.         printf("Usage: SFIND <string to search>");
  46.         exit(1);
  47.     }
  48.     string=strupr(argv[1]);
  49.     
  50.     if( (numfound = fsearch(string)) && numfound != -1)
  51.         display_fileinfo(numfound,string);
  52.     else
  53.         printf("\n0 files found containing \"%s\"\n",string);
  54. }
  55.  
  56.     /* fsearch()
  57.         Allocates the search buffer.
  58.         Finds the first .DOC file in the current directory.
  59.         Skips past header of .DOC file.
  60.         Calls scompare() to read the remainder of the file and search for
  61.             the string.
  62.         If found, puts the file information into a structure of the
  63.             fdata array.
  64.         Continues until all .DOC files are processed.
  65.         Returns -1 on memory allocation error.
  66.         Otherwise, returns the number of files found that contain the string.
  67.     */
  68. fsearch(const char *string)
  69. {
  70.     int flag;                      /*equals 0 while *.DOC files are found*/
  71.     long loop;                     /*counts loops for files>30k*/
  72.     int ct=0;                      /*keeps count of files found*/
  73.     char *ffind='\0';              /*not equal to '\0' if string found*/
  74.     FILE *ptr;                     /*pointer to FILE structure*/
  75.     char *buffer;                  /*holds text from file*/
  76.  
  77.     if(!(buffer=(char *)malloc(BUFSIZE+1)))
  78.     {
  79.         printf("Memory allocation error");
  80.         return(-1);
  81.     }
  82.  
  83.         /* find the first file, then find all of the rest */
  84.     for( flag=(_dos_findfirst("*.doc",_A_NORMAL,&ff_area));    !flag;
  85.         flag = (_dos_findnext(&ff_area)))      
  86.     {
  87.         if(!(ptr=fopen(ff_area.name,"rb")))
  88.         {
  89.             printf("\nsfind: unable to open %.13s\n",ff_area.name);
  90.             continue;
  91.         }
  92.         printf("SEARCHING %.13s\n",ff_area.name);
  93.         
  94.                                 /* skip WORD_HEADER_SIZE bytes of WORD code */
  95.         fseek(ptr,(long)WORD_HEADER_SIZE,SEEK_SET);        
  96.     
  97.                                 /*if file too large for buffer */
  98.         if((ff_area.size-WORD_HEADER_SIZE) > BUFSIZE)      
  99.         {
  100.             for(loop = ff_area.size-WORD_HEADER_SIZE; loop && !ffind;
  101.                 loop -= BUFSIZE)
  102.                 ffind=scompare(ptr,buffer,string,BUFSIZE);
  103.         }
  104.         else
  105.             ffind=scompare(ptr,buffer,string,
  106.                 (int)(ff_area.size-WORD_HEADER_SIZE));
  107.     
  108.         if(ffind)                          /*if string found...*/
  109.         {
  110.             strncpy(fdata[ct].fname,ff_area.name,13); /*save file data*/
  111.             fdata[ct].attrib=ff_area.attrib;
  112.             fdata[ct].fhour=DHOUR(ff_area.wr_time);
  113.             fdata[ct].fmin=DMIN(ff_area.wr_time);
  114.             fdata[ct].fsec=DSEC(ff_area.wr_time);
  115.             fdata[ct].fday=DDAY(ff_area.wr_date);
  116.             fdata[ct].fmon=DMON(ff_area.wr_date);
  117.             fdata[ct].fyear=DYEAR(ff_area.wr_date);
  118.             fdata[ct].fsize=ff_area.size;
  119.             ++ct;
  120.             if(ct == MAXFILES)
  121.                 break;
  122.         }        
  123.         fclose(ptr);
  124.         ffind='\0';                          /*reset to NULL*/
  125.     }                                        /*end of FOR loop*/
  126.     free(buffer);
  127.     return(ct);
  128. }
  129.  
  130.     /* display_fileinfo()
  131.         Prints information on each file that contains the string.
  132.      */
  133. display_fileinfo(int numfound,char *string)
  134. {
  135.     int i;
  136.  
  137.     printf("\n%d file%s contain%s \"%s\":\n",
  138.         numfound,(numfound == 1 ? "" : "s"),(numfound != 1 ? "" : "s"),
  139.             string);
  140.     for(i = 0; i < numfound; ++i)
  141.         printf("%13s %7lu bytes  %02d-%02d-%02d  %02d:%02d:%02d\n",
  142.             fdata[i].fname,
  143.             fdata[i].fsize,
  144.             fdata[i].fmon,
  145.             fdata[i].fday,
  146.             fdata[i].fyear,
  147.             fdata[i].fhour,
  148.             fdata[i].fmin,
  149.             fdata[i].fsec);
  150. }
  151.  
  152.     /* scompare()
  153.         Reads the contents of the file pointed to by ptr. (Up to fsize bytes)
  154.         Uppercases the buffer, to match any case.
  155.         Searches for the string.
  156.         Returns non-zero value if found.
  157.         Otherwise, returns 0.
  158.      */
  159. char *scompare(FILE *ptr,char *buffer,const char *string,int fsize)
  160. {
  161.     char *ffind='\0';                  /*will not equal '\0' if string found*/
  162.     unsigned int numread;              /*number of chars read from file*/
  163.     const char *hold;                  /*pointer to file data to search*/
  164.     
  165.     numread=fread((char *)buffer,sizeof(char),fsize,ptr);
  166.     
  167.     if(numread)                       /*if not an empty file*/
  168.     {
  169.         buffer[numread] = NULL;
  170.         hold = strupr(buffer);        /*capitalize all the characters*/
  171.         ffind = strstr(hold,string);  /*search for string*/
  172.     }
  173.     return(ffind);
  174. }
  175.  
  176.